/**
 * @file   Array.h
 * @author zql <zql@zql-VirtualBox>
 * @date   Wed Oct  6 00:10:32 2021
 * 
 * @brief  a demo
 * 
 * 
 */

#ifndef ZQL_ARRAY
#define ZQL_ARRAY

#include<iostream>
using namespace std;

template <typename T>//可define TEMP template <typename T>
class Array
{
private:
    int size = 0;
    T* elements = NULL;
    void copyMemory(const T* _s, T* _d, int _n);//重复使用的功能可抽象成函数
    void clearMemory();
    void warning(int _err);
public:
    Array(){};//默认构造函数
    Array(const Array& _obj);//复制构造函数
    const Array& operator = (const Array& _obj);//运算符重载
    ~Array();//析构函数
    
    void printArray() const;//不改变类内元素
    void makeEmpty();
    bool isEmpty() const;
    int find(const T& _val) const;
    void insert(int _p, const T& _val);
    void remove(int _p);
  
};

template <typename T>
void Array<T>::clearMemory()
{
    if (elements != NULL)
	delete [] elements;
}

template <typename T>
const Array<T>& Array<T>::operator = (const Array<T>& _obj)
{
    size = _obj.size;
    clearMemory();
    if (size == 0)
    {
	elements = NULL;
	return *this;
    }
    elements = new T [size];
    copyMemory(_obj.elements, elements, size);
    return *this;
}
    
template <typename T>
void Array<T>::copyMemory(const T* _s, T* _d, int _n)//s不改变
{
    for (int i = 0; i < _n; i++)
	_d[i] = _s[i];
}

template <typename T>
Array<T>::Array(const Array& _obj)//函数名不展开，参数可展开
{
    size = _obj.size;
    if (size == 0)
    {
	elements = NULL;
	return;
    }//复制构造函数，此前elements为空不需要判断指针
    elements = new T [size];
    copyMemory(_obj.elements, elements, size);
}

template <typename T>
Array<T>::~Array()
{
    clearMemory();
}

template <typename T>
void Array<T>::printArray() const
{
    if (isEmpty())
	return;
    for (int i = 0; i < size; i++)
	cout << elements[i] << ", ";
    cout << "\b\b." << endl;
}

template <typename T>
void Array<T>::makeEmpty()
{
    size = 0;//封装性，其实数据还在
}

template <typename T>
bool Array<T>::isEmpty() const
{
    if (size == 0)
	return true;
    else
	return false;
}

template <typename T>
int Array<T>::find(const T& _val) const
{
    int i = 0;//循环后要用到所以单独写
    bool found = false;
    for(; i < size; i++)
	if (elements[i] == _val)
	{
	    found = true;
	    break;
	}
    if (found == true)
	return i;
    else
	return -1;
}

template <typename T>
void Array<T>::insert(int _p, const T& _val) 
{
    if (_p < 0 || _p > size)//_p = 0时复制不做，直接插入第一个
    {
	warning(1);
	return;
    }
    T* temp_data = new T [size + 1];//暴力解决复杂度仍然是cN
    copyMemory(elements, temp_data, _p);
    temp_data[_p] = _val;
    copyMemory(elements + _p, temp_data + _p +1, size - _p);
    clearMemory();
    elements = temp_data;//指针指向临时指针
    size++;
}

template <typename T>
void Array<T>::warning(int _err)
{
    switch (_err)
    {
    case 1:
	cerr << "Out of range!" << endl;
	break;
    default:
	cerr << "Unexpected error!" << endl;
    }
}

template <typename T>
void Array<T>::remove(int _p)
{
    if (_p < 0 || _p > size)
    {
	warning(1);
	return;
    }
    copyMemory(elements + _p + 1, elements + _p, size - _p - 1);
    size--;
}

#else
//do nothing
#endif
    
	




